#include "chatwindow.h"

#include <QMenuBar>
#include <QAction>
#include <QTextEdit>
#include <QListWidget>
#include <QListWidgetItem>
#include <QVBoxLayout> 
#include <QHBoxLayout> 
#include <QTime>
#include <QIcon>
#include <QMenu>
#include <QSplitter>
#include <QPushButton>
#include <QInputDialog>
#include <QMessageBox>
#include <QLabel>

#include "common/chat.h"
#include "common/friend.h"

namespace Ui{

ChatWindow::ChatWindow(Chat *chat, Friend *me, QWidget *parent) : QMainWindow(parent), chat(chat), me(me) {
	terminated = false;
	setWindowIcon(QIcon("data/img/chat.png"));

	chatMenu=new QMenu(tr("&Chat"));
	inviteFriend=chatMenu->addAction(tr("&Invite"));
	chatMenu->addSeparator();
	quitChatAction=chatMenu->addAction(tr("&Quit"));

	connect(inviteFriend,SIGNAL(triggered()),this,SLOT(invite()));
	connect(quitChatAction,SIGNAL(triggered()),this,SLOT(quit()));

	menuBar()->addMenu(chatMenu);
	createCentralWidget();

	foreach(Friend *f,chat->getFriends()){
		if(f->getId()!=me->getId()){
			addFriend(f);
		}
	}
}

void ChatWindow::createCentralWidget() {
	friendsMenu =new QMenu(tr("&Friend"), this);

	friendsList = new QListWidget();

	addIcon = new QPushButton(QIcon("data/img/add.png"),"");
	connect(addIcon, SIGNAL(clicked()), this, SLOT(invite()));

	editor = new QTextEdit();
	editor->setTabChangesFocus(true);
	connect(editor, SIGNAL(textChanged()), this, SLOT(textChanged()));

	display = new QTextEdit();
	display->setReadOnly(true);
	
	send = new QPushButton("Send");
	send->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
	send->setDisabled(true);

	nFriends=1;
	
	friendsList = new QListWidget();	
	friendsCount = new QLabel(QString::number(nFriends)+" users chatting");
	friendsCount->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum));
	friendsHLayout = new QHBoxLayout();
	friendsHLayout->addWidget(friendsCount);
	friendsHLayout->addWidget(addIcon);
	friendsVLayout = new QVBoxLayout();
	friendsVLayout->addLayout(friendsHLayout);
	friendsVLayout->addWidget(friendsList);

	QWidget *friendsWidget=new QWidget(this);
	friendsWidget->setLayout(friendsVLayout);
	
	displayFriendsListSplitter=new QSplitter(Qt::Horizontal,this);
	displayFriendsListSplitter->addWidget(display);
	displayFriendsListSplitter->addWidget(friendsWidget);
	displayFriendsListSplitter->setStretchFactor(0,4);
	displayFriendsListSplitter->setChildrenCollapsible(false);
	
	editorSendSplitter = new QSplitter(Qt::Horizontal,this);
	editorSendSplitter->addWidget(editor);
	editorSendSplitter->addWidget(send);
	editorSendSplitter->setStretchFactor(0,4);
	editorSendSplitter->setChildrenCollapsible(false);

	vsplitter=new QSplitter(Qt::Vertical,this);
	vsplitter->addWidget(displayFriendsListSplitter);
	vsplitter->addWidget(editorSendSplitter);
	vsplitter->setStretchFactor(0,10);
	vsplitter->setChildrenCollapsible(false);

	mainLayout = new QVBoxLayout();
	mainLayout->addWidget(vsplitter);
	
	QWidget *widget = new QWidget(this);
	widget->setLayout(mainLayout);

	setCentralWidget(widget);

	connect(send, SIGNAL(clicked()), this, SLOT(newOutcomingMessage()));
}

ChatWindow::~ChatWindow(){
	if(chat) delete chat;
	if(quitChatAction) delete quitChatAction;
	if(inviteFriend) delete inviteFriend;
	if(chatMenu) delete chatMenu;
	if(friendsMenu) delete friendsMenu;
	if(displayFriendsListSplitter) delete displayFriendsListSplitter;
	if(editorSendSplitter) delete editorSendSplitter;
	if(vsplitter) delete vsplitter;
	if(editor) delete editor;
	if(display) delete display;
	if(friendsList) delete friendsList;
	if(send) delete send;
	if(mainLayout) delete mainLayout;
}

void ChatWindow::newIncomingMessage(Friend* _friend,const QString& _text) {
	QString message;
	message += "(" + QTime::currentTime().toString() + ") ";
	message += _friend->getName() + ": " + _text;
	display->append(message);
}	

void ChatWindow::newOutcomingMessage() {
	emit newOutcomingMessage(editor->toPlainText(),chat);
	QString message;
	message += "(" + QTime::currentTime().toString() + ") ";
	message += "Me: " + editor->toPlainText();
	display->append(message);
	editor->clear();
	editor->setFocus();
}

void ChatWindow::newEventMessage(ChatEvent event, Friend* _friend) {
	QString message;
	message += "(" + QTime::currentTime().toString() + ")";
	switch(event) {
		case Join: {
			nFriends++;
			friendsCount->setText(QString::number(nFriends)+" users chatting");
			QString title("Chat with:");
			foreach(Friend *f,chat->getFriends()){
				if(f->getId()!=me->getId()){
					title += " "+f->getName();
				}
			}
			message += " <b>Join:</b> " + _friend->getName();
			break;
		}
		case Quit: {
			nFriends--;
			friendsCount->setText(QString::number(nFriends)+" users chatting");
			QString title("Chat with:");
			foreach(Friend *f,chat->getFriends()){
				if(f->getId()!=me->getId()){
					title += " "+f->getName();
				}
			}
			message += " <b>Quit:</b> " + _friend->getName();
			break;
		}
		case StatusChange:
			message += " <b>Status changed:</b> " + _friend->getName() + " became ";
			switch(_friend->getStatus()) {
				case Online:
					message += "Online";
					break;
				case Away:
					message += "Away";
					break;
				case Offline:
					message += "Offline";
					break;
				default:
					break;
			}
			break;
		default:
			break;

	}	
	display->append(message);
}

void ChatWindow::addFriend(Friend* _friend) {
	QListWidgetItem* item = new QListWidgetItem();
	item->setText(_friend->getName());
	friendsListItens[_friend->getId()] = item;
	item->setIcon(getStatusIcon(_friend->getStatus()));
	
	friendsList->addItem(item);
	if(!chat->containsFriend(_friend)) chat->addFriend(_friend);

	newEventMessage(Join, _friend);
	updateTitle();
}

void ChatWindow::removeFriend(Friend* _friend) {
	chat->removeFriend(_friend);
	updateTitle();
	newEventMessage(Quit, _friend);
	foreach(QListWidgetItem *item, friendsList->findItems(_friend->getName(),Qt::MatchExactly)) {
		friendsList->removeItemWidget(item);
	}
}

void ChatWindow::terminate() {
	friendsList->clear();
	QMessageBox::critical(this,"Chat terminated","This chat has been terminated because all other contacts got out.",QMessageBox::Ok,QMessageBox::Ok);
	terminated=true;
	close();
}
void ChatWindow::updateStatusFriend(Friend* _friend) {
	newEventMessage(StatusChange, _friend);
	QListWidgetItem* item = friendsListItens[_friend->getId()];
	item->setIcon(getStatusIcon(_friend->getStatus()));
}	

void ChatWindow::invite() {
	bool ok;
	QString text = QInputDialog::getText(this, tr("Invite Friend"), tr("Login:"), QLineEdit::Normal, "", &ok);
	if(ok && !text.isEmpty()) {
		emit inviteChat(chat,text) ;
		QMessageBox::information(this, "Invitation", "Your invitation has been sent.");
	}
}
void ChatWindow::closeEvent(QCloseEvent *event) {
	if(!terminated)
		quit();	
}

QIcon ChatWindow::getStatusIcon(Status _status) const {
	switch(_status) {
		case Online:
			return QIcon("data/img/online.png");
		case Away:
			return QIcon("data/img/away.png");
		case Inactivity:
			return QIcon("data/img/inactivity.png");
		default:
			return QIcon("data/img/offline.png");
	}
}

void ChatWindow::updateTitle() {
	QString title("Chat with:");
	foreach(Friend *f,chat->getFriends()){
		if(f->getId()!=me->getId()){
			title += " "+f->getName();
		}
	}
	setWindowTitle(title);
}

void ChatWindow::quit(){
	emit quitChat(chat);
}

void ChatWindow::textChanged(){
	send->setDisabled(editor->toPlainText().isEmpty());
}

}

